package com.beantools.util.poutil;

import com.beantools.constants.PropertyTypeName;
import com.beantools.execption.PropertyException;

import static com.beantools.constants.MainASCCode.ASC_UPPER_A;
import static com.beantools.constants.MainASCCode.ASC_UPPER_Z;
import static com.beantools.constants.MethodPrefix.*;
import static com.beantools.util.StringUtil.isBlank;
import static com.beantools.util.StringUtil.isNotBlank;

/**
 * 该类是操作属性的工具类
 *
 * @author baoya
 * @version 1.0
 * @since 1.1.0
 */
public class PropertyUtil {

    /**
     * 该方法是将属性转化为set方法，比如将属性{@code public String name}转化为
     * {@code setPropertyName}方法,但如果遇到属性的首字母小写，但第二个字母大写，比如
     * {@code public String nAme},这就需要抛出异常。
     * <p>
     * 同时，如果属性的类型是boolean，需要将其转化为is开头的方法，比如{@code
     * public boolean deleted},其转化后的的方法是{@code isDeleted}
     *
     * @param propertyName 类属性名称
     * @param typeName     属性类型名，需要区分是不是Boolean类型
     * @return 如果条件成立，则返回setter方法
     */
    public static String propNameTransformSetter(String typeName, String propertyName, Class persistClass) {
        return (isNotBlank(typeName) && typeName.equalsIgnoreCase(PropertyTypeName.TYPE_NAME_BOOLEAN) ? PREFIX_IS : PREFIX_SET)
                + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
    }

    /**
     * 该方法是将属性转化为get方法，比如将属性{@code public String name}转化为
     * {@code getPropertyName}方法；如果属性的类型是boolean，需要将其转化为is开头的方法，
     * 比如{@code public boolean deleted},其转化后的的方法是{@code isDeleted}
     * <p>
     * 这里不包括booleanl类型的填充数据，Boolean类型的数据比较特殊，单独处理
     *
     * @param propertyName 类属性名称
     * @param typeName     属性类型名，需要区分是不是Boolean类型
     * @return 如果条件成立，则返回getter方法
     */
    public static String propNameTransformGetter(String typeName, String propertyName) {
        return (isNotBlank(typeName) && typeName.equalsIgnoreCase(PropertyTypeName.TYPE_NAME_BOOLEAN) ? PREFIX_IS : PREFIX_GET)
                + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);

    }

    /**
     * 当前方法是静态方法，如果属性名的字母为null或为空字符，则返回false，
     * 如果属性名的字母的长度是1，则返回false，如果属性名的长度是两个或两
     * 个以上，首字母和第二个字母不大写，则返回true，否则，返回false
     *
     * @param propertyName 属性名称
     * @return 如果属性的第二个字母不是大写，则返回true，否则，返回false
     * @throws PropertyException 属性异常，如果属性为空，或不存在，或是单字母，就会
     */
    public static boolean beforeSecondLetterUppercase(String propertyName) throws PropertyException {
        if (isBlank(propertyName)) {
            throw new PropertyException("为空，或不存在", propertyName);
        }
        if (isOneLetter(propertyName)) {
            throw new PropertyException("不能是单字母", propertyName);
        }
        char[] nameChars = propertyName.toCharArray();
//        首字母和第二个字母均不能大写
        boolean trueArea = (nameChars[0] >= ASC_UPPER_A && nameChars[0] <= ASC_UPPER_Z) || (nameChars[1] >= ASC_UPPER_A && nameChars[1] <= ASC_UPPER_A);
        return trueArea ? true : false;
    }

    /**
     * 当前方法是静态方法，如果属性名的字母为null或为空字符，则返回false，
     * 不如果属性名的字母的长度是1，则返回true，否则，返回false
     *
     * @param propertyName 属性名称
     * @return 如果属性名称的长度为1，说明该属性名只有一个字母，则返回true
     * 否则，返回false
     */
    public static boolean isOneLetter(String propertyName) {
        return isNotBlank(propertyName) && propertyName.length() == 1 ? true : false;
    }
}
